package com.andatsoft.laisim.dialog;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.TextView;

import com.andatsoft.laisim.R;
import com.andatsoft.laisim.activity.BaseActivity;
import com.andatsoft.laisim.adapter.ScanFolderExpandableListAdapter;
import com.andatsoft.laisim.adapter.ScanFolderExpandableListAdapter.onSavedFolderChangedListerner;
import com.andatsoft.laisim.entity.FolderItem;
import com.andatsoft.laisim.utils.Utils;
import com.andatsoft.laisim.view.WPProgressBar;

public class ScanFolderDialog extends BaseActivity implements
		onSavedFolderChangedListerner {

	private ExpandableListView mExpandalbeListView;
	private TextView mTvOk;
	private WPProgressBar mProgress;

	private ScanFolderExpandableListAdapter mAdapter;

	private List<FolderItem> mGroupItems;
	private HashMap<String, List<FolderItem>> mChildItems;
	private List<String> mSavedFolder;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getWindow().requestFeature(Window.FEATURE_NO_TITLE);
		getWindow().setBackgroundDrawable(
				new ColorDrawable(getResources().getColor(R.color.black)));
		setContentView(R.layout.dialog_scan_folder);

		mGroupItems = new ArrayList<FolderItem>();
		mChildItems = new HashMap<String, List<FolderItem>>();
		mAdapter = new ScanFolderExpandableListAdapter(getApplicationContext(),
				mGroupItems, mChildItems);
		mAdapter.setOnSavedFolderGroupChangedListener(this);

		mTvOk = (TextView) findViewById(R.id.tv_scan_folder_dialog_ok);
		mTvOk.setEnabled(false);
		mTvOk.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					for (String fi : mSavedFolder) {
						Log.e("Saved:", fi);
					}
					saveFolder();
					ScanFolderDialog.this.finish();
					break;
				}
				return false;
			}
		});
		mProgress = (WPProgressBar) findViewById(R.id.progress_scan_folder_dialog);
		mExpandalbeListView = (ExpandableListView) findViewById(R.id.expand_list_scan_folder_dialog);
		mExpandalbeListView.setOnGroupClickListener(new OnGroupClickListener() {

			@Override
			public boolean onGroupClick(ExpandableListView parent, View v,
					int groupPosition, long id) {
				if (mGroupItems.get(groupPosition).isSelected) {
					return true;
				}
				return false;
			}
		});
		mExpandalbeListView.setOnChildClickListener(new OnChildClickListener() {

			@Override
			public boolean onChildClick(ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {
				FolderItem item = mChildItems.get(
						mGroupItems.get(groupPosition).folderName).get(
						childPosition);
				if (item.isSelected) {
					item.isSelected = false;
					mSavedFolder.remove(item.folderName);
				} else {
					item.isSelected = true;
					mSavedFolder.add(item.folderName);
				}
				mAdapter.notifyDataSetChanged();
				return false;
			}
		});
		new FolderScanner().execute(Environment.getExternalStorageDirectory()
				.getParent());
	}

	private void saveFolder() {
		try {
			FileOutputStream fos = openFileOutput("sf.ls", Context.MODE_PRIVATE);
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			oos.writeObject(mSavedFolder);
			oos.flush();
			oos.close();
			fos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	class FolderScanner extends AsyncTask<String, Void, Void> {

		@Override
		protected void onPreExecute() {
			mProgress.setVisibility(View.VISIBLE);
		}

		@Override
		protected Void doInBackground(String... params) {
			// String path = params[0];
			// String[] a =
			String[] fL = Utils.getAllStoragePath();
			if (fL != null && fL.length > 0) {
				getSavedFolder();
				if (mSavedFolder == null)
					mSavedFolder = new ArrayList<String>();
				FolderItem fi;
				for (int i = 0; i < fL.length; i++) {
					fi = new FolderItem();
					fi.folderName = fL[i];
					if (mSavedFolder.contains(fi.folderName)) {
						fi.isSelected = true;
					}
					mGroupItems.add(fi);
					// add child view
					File[] childs = new File(fL[i]).listFiles(new FileFilter() {

						@Override
						public boolean accept(File pathname) {
							if (pathname.isDirectory())
								return true;
							return false;
						}
					});
					if (childs != null && childs.length > 0) {
						List<FolderItem> items = new ArrayList<FolderItem>();
						for (int j = 0; j < childs.length; j++) {
							fi = new FolderItem();
							fi.folderName = childs[j].getAbsolutePath();
							if (mSavedFolder.contains(fi.folderName)) {
								fi.isSelected = true;
							}
							items.add(fi);
						}
						mChildItems.put(fL[i], items);
					}
				}
			}
			return null;
		}

		@SuppressWarnings("unchecked")
		private void getSavedFolder() {
			try {
				FileInputStream fis = openFileInput("sf.ls");
				ObjectInputStream ois = new ObjectInputStream(fis);
				mSavedFolder = (List<String>) ois.readObject();
				if (mSavedFolder == null)
					mSavedFolder = new ArrayList<String>();
				ois.close();
				fis.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (StreamCorruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		@Override
		protected void onPostExecute(Void result) {
			mExpandalbeListView.setAdapter(mAdapter);
			mProgress.setVisibility(View.INVISIBLE);
			mTvOk.setEnabled(true);
			// update expand
			for (int i = 0; i < mGroupItems.size(); i++)
				updateIfChildInGroup(i);
		}

	}

	@Override
	public void onGroupFolderChanged(int groupIndex, boolean isSelect) {
		if (isSelect) {
			if (!mSavedFolder.contains(mGroupItems.get(groupIndex).folderName)) {
				mSavedFolder.add(mGroupItems.get(groupIndex).folderName);
				// remove all child in this group
				removeChildInGroup(groupIndex);
			}
			mExpandalbeListView.collapseGroup(groupIndex);
			mGroupItems.get(groupIndex).isSelected = true;
		} else {
			mSavedFolder.remove(mGroupItems.get(groupIndex).folderName);
			mGroupItems.get(groupIndex).isSelected = false;
			updateIfChildInGroup(groupIndex);
		}
		mAdapter.notifyDataSetChanged();
	}

	private void updateIfChildInGroup(int groupIndex) {
		List<FolderItem> re = mChildItems
				.get(mGroupItems.get(groupIndex).folderName);
		if (re == null)
			return;
		for (FolderItem fI : re) {
			if (fI.isSelected) {
				// this group has at least a child selected-->expand it
				mExpandalbeListView.expandGroup(groupIndex);
			}
		}
	}

	private void removeChildInGroup(int groupIndex) {
		List<FolderItem> re = mChildItems
				.get(mGroupItems.get(groupIndex).folderName);
		if (re != null) {
			for (FolderItem fI : re) {
				if (fI.isSelected) {
					mSavedFolder.remove(fI.folderName);
				}
			}
		}
	}	

}
